package com.lowcode.platform.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lowcode.platform.common.PageResult;
import com.lowcode.platform.common.Result;
import com.lowcode.platform.dto.FileUploadResponse;
import com.lowcode.platform.entity.SysFile;
import com.lowcode.platform.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * 文件控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/file")
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * 普通文件上传
     */
    @PostMapping("/upload")
    public Result<FileUploadResponse> upload(
            @RequestParam("file") MultipartFile file,
            @RequestParam(required = false, defaultValue = "1") Long userId) {
        FileUploadResponse response = fileService.uploadFile(file, userId);
        return Result.success(response);
    }

    /**
     * 分片上传
     */
    @PostMapping("/upload/chunk")
    public Result<Void> uploadChunk(
            @RequestParam("chunk") MultipartFile chunk,
            @RequestParam("md5") String md5,
            @RequestParam("chunkNumber") Integer chunkNumber,
            @RequestParam("totalChunks") Integer totalChunks) {
        fileService.uploadChunk(chunk, md5, chunkNumber, totalChunks);
        return Result.success();
    }

    /**
     * 合并分片
     */
    @PostMapping("/upload/merge")
    public Result<FileUploadResponse> mergeChunks(
            @RequestParam("md5") String md5,
            @RequestParam("fileName") String fileName,
            @RequestParam("totalChunks") Integer totalChunks,
            @RequestParam(required = false, defaultValue = "1") Long userId) {
        FileUploadResponse response = fileService.mergeChunks(md5, fileName, totalChunks, userId);
        return Result.success(response);
    }

    /**
     * 检查分片上传状态（断点续传）
     */
    @GetMapping("/upload/check-chunks")
    public Result<Integer> checkChunks(@RequestParam("md5") String md5) {
        Integer uploadedChunks = fileService.getUploadedChunks(md5);
        return Result.success(uploadedChunks);
    }

    /**
     * 检查文件是否存在（秒传）
     */
    @GetMapping("/check")
    public Result<FileUploadResponse> checkFile(@RequestParam("md5") String md5) {
        FileUploadResponse response = fileService.checkFile(md5);
        return Result.success(response);
    }

    /**
     * 分页查询文件
     */
    @GetMapping("/page")
    public Result<PageResult<SysFile>> page(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size,
            @RequestParam(required = false) String fileName) {
        
        Page<SysFile> page = new Page<>(current, size);
        LambdaQueryWrapper<SysFile> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(fileName)) {
            wrapper.like(SysFile::getFileName, fileName);
        }
        wrapper.orderByDesc(SysFile::getCreateTime);
        
        IPage<SysFile> result = fileService.page(page, wrapper);
        
        PageResult<SysFile> pageResult = new PageResult<>(
                result.getTotal(),
                result.getRecords(),
                result.getCurrent(),
                result.getSize()
        );
        
        return Result.success(pageResult);
    }

    /**
     * 文件下载
     */
    @GetMapping("/download/{id}")
    public void download(@PathVariable Long id, HttpServletResponse response) {
        try {
            SysFile sysFile = fileService.getById(id);
            if (sysFile == null) {
                response.setStatus(404);
                return;
            }

            File file = new File(sysFile.getFilePath());
            if (!file.exists()) {
                response.setStatus(404);
                return;
            }

            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", 
                    "attachment; filename=" + URLEncoder.encode(sysFile.getFileName(), "UTF-8"));
            response.setContentLengthLong(file.length());

            try (FileInputStream fis = new FileInputStream(file);
                 OutputStream os = response.getOutputStream()) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.flush();
            }
        } catch (Exception e) {
            log.error("文件下载失败", e);
            response.setStatus(500);
        }
    }

    /**
     * 删除文件
     */
    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        SysFile sysFile = fileService.getById(id);
        if (sysFile != null) {
            // 删除物理文件
            File file = new File(sysFile.getFilePath());
            if (file.exists()) {
                file.delete();
            }
            // 删除数据库记录
            fileService.removeById(id);
        }
        return Result.success();
    }
}
